package com.corpgovernment.travelstandard.impl;

import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.ObjectUtil;
import com.corpgovernment.api.organization.model.post.PostVo;
import com.corpgovernment.api.travelstandard.bo.CarDescBO;
import com.corpgovernment.api.travelstandard.bo.CarStandardResponseBO;
import com.corpgovernment.api.travelstandard.enums.*;
import com.corpgovernment.api.travelstandard.service.IMbTravelstandCarService;
import com.corpgovernment.api.travelstandard.vo.MbTravelstandReasonCodeVo;
import com.corpgovernment.api.travelstandard.vo.Node;
import com.corpgovernment.api.travelstandard.vo.RCListVo;
import com.corpgovernment.api.travelstandard.vo.TravelStandardPostVo;
import com.corpgovernment.api.travelstandard.vo.car.*;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.base.Page;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.enums.ExceptionCodeEnum;
import com.corpgovernment.common.utils.*;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.service.IPostService;
import com.corpgovernment.travelstandard.constant.ServiceConstant;
import com.corpgovernment.travelstandard.entity.db.*;
import com.corpgovernment.travelstandard.mapper.MbTravelstandCarMapper;
import com.corpgovernment.travelstandard.utils.BeanConverUtil;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.ctrip.corp.obt.shard.context.PageContext;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

import static com.corpgovernment.travelstandard.constant.ServiceConstant.UPPER_LIMIT_TIMES_OF_TRAVEL_STANDARD;

@Service
public class MbTravelstandCarService extends TravelStandardBaseService implements IMbTravelstandCarService {

    private final static String[] CAR_RC_TEMPS = {"carRcCpTemp", "carRcCmTemp","carRcCdTemp"};


	@Autowired
	private MbTravelstandReasonCodeService travelstandReasonCodeService;
	@Autowired
	private MbTravelstandCarMapper mbTravelstandCarMapper;
	@Autowired
	private MbTravelstandCarModelService mbTravelstandCarModelService;
	@Autowired
	private TravelStandardPostService travelStandardPostService;
	@Autowired
	private IPostService postService;
	@Autowired
	private TravelStandardPostService standPostService;
	@Autowired
	private MbTravelstandCarDatetimeService mbTravelstandCarDatetimeService;
	@Autowired
    private MbTravelStandCarCityService mbTravelStandCarCityService;
	@Autowired
    private MbTravelStandCarAddressService mbTravelStandCarAddressService;
    @Autowired
    private MbTravelStandCarCrossCityService mbTravelStandCarCrossCityService;
    @Autowired
    private MbTravelStandCarTimesService mbTravelStandCarTimesService;


	@Override
	public void insert(MbTravelstandCarVo model) {
		MbTravelstandCar insertParam = ObjectUtils.copyProperties(model, MbTravelstandCar.class);
		if (insertParam == null) {
			return;
        }
        mbTravelstandCarMapper.insertSelective(insertParam);
    }

    @Override
    public int delete(Long id) {
        return mbTravelstandCarMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int update(MbTravelstandCarVo model) {
        MbTravelstandCar updateParam = ObjectUtils.copyProperties(model, MbTravelstandCar.class);
        if (updateParam == null || updateParam.getId() == null) {
            return 0;
        }
        return mbTravelstandCarMapper.updateByPrimaryKeySelective(updateParam);
    }

    @Override
    public MbTravelstandCarVo get(Long id) {
        MbTravelstandCar result = mbTravelstandCarMapper.selectByPrimaryKey(id);
        if (result == null) {
            return null;
        }
        return ObjectUtils.copyProperties(result, MbTravelstandCarVo.class);
    }

    @Override
    public Page page(MbTravelstandCarVo model) {
        MbTravelstandCar param = ObjectUtils.copyProperties(model, MbTravelstandCar.class);
        PageContext.startPage(model.getPageNum(), model.getPageSize());
        List<MbTravelstandCar> list = mbTravelstandCarMapper.list(param);
        return PageUtils.optPageBy(list, MbTravelstandCarVo.class);
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertTravelstandCar(MbTravelstandCarVo model) {
        MbTravelstandCar mbTravelstandCar = ObjectUtils.copyProperties(model, MbTravelstandCar.class);
        mbTravelstandCar.setDatachangeCreatetime(new Date());
        mbTravelstandCar.setDatachangeLasttime(new Date());
        mbTravelstandCarMapper.insert(mbTravelstandCar);
        model.setId(mbTravelstandCar.getId());
        //从apollo获取默认RC
        insertTravelstandReasonCode(CAR_RC_TEMPS, model.getId());
        //批量插入车型信息（默认全部选中）
        for (CarModelEnum carModelEnum : CarModelEnum.values()) {
            MbTravelstandCarModelVo mbTravelstandCarModelVo = new MbTravelstandCarModelVo();
            mbTravelstandCarModelVo.setTsCarId(model.getId());
            mbTravelstandCarModelVo.setModelName(carModelEnum.getName());
            mbTravelstandCarModelVo.setModelCode(carModelEnum.getCode());
			mbTravelstandCarModelVo.setTsType(TravelStandardTypeEnum.Car.getCode());
            mbTravelstandCarModelService.insert(mbTravelstandCarModelVo);
        }
//        insertOperateLog(coverMbTravelstandTrainVoToTrainOperateLogVo(model));
    }



    @Transactional(rollbackFor = Exception.class)
    public void updateCarTravelStandardProperty(CarManageVo carManageVo) {
        // 参数校验
        checkRequestParam(carManageVo);
        String id = carManageVo.getId();
        if (StringUtils.isBlank(id)) {
            throw new CorpBusinessException(ExceptionCodeEnum.Alert, "获取不到差标id,请刷新再试!");
        }
        String jobScopeId = carManageVo.getJobScopeId();
        if (StringUtils.isBlank(jobScopeId)) {
            throw new CorpBusinessException(ExceptionCodeEnum.Alert, "请选择职级范围");
        }
        String orgId = carManageVo.getOrgId();
        if (StringUtils.isBlank(orgId)) {
            throw new CorpBusinessException(ExceptionCodeEnum.Alert, "无法获取公司信息!");
        }
        PriceControl priceControl = carManageVo.getPriceControl();
        if (priceControl == null) {
            throw new CorpBusinessException(ExceptionCodeEnum.Alert, "价格控制数据有误!");
        }
        ModelControl modelControl = carManageVo.getModelControl();
        if (modelControl == null) {
            throw new CorpBusinessException(ExceptionCodeEnum.Alert, "车型控制数据有误!");
        }

        DatetimeControl datetimeControl = carManageVo.getDatetimeControl();


        if (datetimeControl == null) {
            datetimeControl = new DatetimeControl();
            datetimeControl.setStatus(CarSwitchEnum.DatetimeSwitch.N.getCode());
            datetimeControl.setDatetimeRcSet(ControlTypeEnum.F.getCode());
        } else {
            List<CarDatetimeVo> carDatetimes = datetimeControl.getCarDatetimes();
            for (int i = 0; i < carDatetimes.size(); i++) {
                if(CarSwitchEnum.CarCitySwitch.N.getCode().equals(datetimeControl.getStatus())){
                    break;
                }
                CarDatetimeVo item = carDatetimes.get(i);
                if (item.get_times()==null){
                    continue;
                }
                if (StringUtils.isBlank(item.get_times().getStartHour()) || StringUtils.isBlank(item.get_times().getEndHour())){
                    throw new CorpBusinessException(ExceptionCodeEnum.Alert, "开始时间和结束时间都不能为空!");
                }
                if ((item.get_times().getStartHour()+":"+item.get_times().getStartMin()).equals( (item.get_times().getEndHour()+":"+item.get_times().getEndMin())) ){
                    throw new CorpBusinessException(ExceptionCodeEnum.Alert, "开始时间不能等于结束时间!");
                } else {
                    if( Integer.parseInt(item.get_times().getStartHour())<24){
                        item.setStartTime(item.get_times().getStartHour()+":"+item.get_times().getStartMin());
                    }else {
                        item.setStartTime(BeanConverUtil.addZeroForStr(String.valueOf(Integer.parseInt(item.get_times().getStartHour())-24),2,1)+":"+item.get_times().getStartMin());
                    }

                    if(Integer.parseInt(item.get_times().getEndHour())<24){
                        item.setEndTime(item.get_times().getEndHour()+":"+item.get_times().getEndMin());
                    }else {
                        item.setEndTime(BeanConverUtil.addZeroForStr(String.valueOf(Integer.parseInt(item.get_times().getEndHour())-24),2,1)+":"+item.get_times().getEndMin());
                    }
                }
            }
        }

        MbTravelstandCarVo oriMbTravelstandCarVo = get(Long.valueOf(id));
        if (oriMbTravelstandCarVo == null) {
            throw new CorpBusinessException(ExceptionCodeEnum.Alert, "差标不存在!");
        }
        CarCityControl carCityControl = carManageVo.getCarCityControl();
        if (carCityControl == null) {
            carCityControl = new CarCityControl();
            carCityControl.setStatus(CarSwitchEnum.CarCitySwitch.N.getCode());
            carCityControl.setCarCityRcSet(ControlTypeEnum.F.getCode());
        }else {
            if(carCityControl != null && carCityControl.getCrossCityControlVo() != null){
                CarCrossCityControlVo carCrossCityControlVo = carCityControl.getCrossCityControlVo();
                if(carCrossCityControlVo.getControlType()!=null && carCrossCityControlVo.getControlType() == 2 && CollectionUtils.isEmpty(carCrossCityControlVo.getCrossCityVos())){
                    throw new CorpBusinessException(ExceptionCodeEnum.Alert, "请选择跨城城市!");
                }
            }
        }


        CarAddressControl carAddressControl = carManageVo.getCarAddressControl();
        if (carAddressControl == null) {
            carAddressControl = new CarAddressControl();
            carAddressControl.setStatus(CarSwitchEnum.CarAddressSwitch.N.getCode());
            carAddressControl.setCarAddressRcSet(ControlTypeEnum.F.getCode());
        }

        CarTimesControl carTimesControl = carManageVo.getCarTimesControl();
        if (carTimesControl == null) {
            carTimesControl = new CarTimesControl();
            carTimesControl.setStatus(CarSwitchEnum.CarAddressSwitch.N.getCode());
            carTimesControl.setCarTimeRCSet(ControlTypeEnum.F.getCode());
        }else {
            if(carTimesControl.getDayTimesCeiling()!=null && carTimesControl.getDayTimesCeiling() > UPPER_LIMIT_TIMES_OF_TRAVEL_STANDARD ){
                throw new CorpBusinessException(ExceptionCodeEnum.Alert, "次数不能大于99!");
            }
            if(carTimesControl.getMonthTimesCeiling()!=null && carTimesControl.getMonthTimesCeiling() > UPPER_LIMIT_TIMES_OF_TRAVEL_STANDARD){
                throw new CorpBusinessException(ExceptionCodeEnum.Alert, "次数不能大于99!");
            }
        }
        //地点差标校验
        checkCarAddress(carAddressControl);


        MbTravelstandCarVo mbTravelstandCarVo = new MbTravelstandCarVo(
                oriMbTravelstandCarVo.getId(),
                oriMbTravelstandCarVo.getOrgId(),
                oriMbTravelstandCarVo.getName(),
                modelControl.getStatus(),
                modelControl.getModelRcSet(),
                priceControl.getStatus(),
                priceControl.getPriceCeiling(),
                priceControl.getDayPriceCeiling(),
                priceControl.getMonthPriceCeiling(),
                priceControl.getPriceRcSet(),
                carManageVo.getSceneCode(),
                carManageVo.getSceneName(),
                datetimeControl.getStatus(),
                datetimeControl.getDatetimeRcSet(),
                carCityControl.getStatus(),
                carCityControl.getCarCityRcSet(),
                carAddressControl.getStatus(),
                carAddressControl.getCarAddressRcSet(),
                carTimesControl.getStatus(),
                carTimesControl.getCarTimeRCSet(),
                "E"
        );
        mbTravelstandCarVo.setProductSwitch(carManageVo.getProductSwitch());
        //更新差标属性
        if (update(mbTravelstandCarVo) != 1) {
            throw new CorpBusinessException(ExceptionCodeEnum.Alert, "差标数据更新失败!");
        }
        //更新价格RC
        if (!CollectionUtils.isEmpty(priceControl.getPriceRcCheckList())) {
            RCListVo rcListVoFc = new RCListVo();
            rcListVoFc.setId(String.valueOf(mbTravelstandCarVo.getId()));
            rcListVoFc.setRcList(priceControl.getPriceRcCheckList());
            rcListVoFc.setRcType(ReasonCodeTypeEnum.CP.getCode());
            rcListVoFc.setTsType(TravelStandardTypeEnum.Car.getCode());
            travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFc);
        }

        //更新车型RC
        if (!CollectionUtils.isEmpty(modelControl.getModelRcCheckList())) {
            RCListVo rcListVoFl = new RCListVo();
            rcListVoFl.setId(String.valueOf(mbTravelstandCarVo.getId()));
            rcListVoFl.setRcList(modelControl.getModelRcCheckList());
            rcListVoFl.setRcType(ReasonCodeTypeEnum.CM.getCode());
            rcListVoFl.setTsType(TravelStandardTypeEnum.Car.getCode());
            travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFl);
        }

        //更新时间RC
        if (!CollectionUtils.isEmpty(datetimeControl.getDatetimeRcCheckList())){
            RCListVo rcListVoFd = new RCListVo();
            rcListVoFd.setId(String.valueOf(mbTravelstandCarVo.getId()));
            rcListVoFd.setRcList(datetimeControl.getDatetimeRcCheckList());
            rcListVoFd.setRcType(ReasonCodeTypeEnum.CD.getCode());
            rcListVoFd.setTsType(TravelStandardTypeEnum.Car.getCode());
            travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFd);
        }
        //更新城市RC
        if (!CollectionUtils.isEmpty(carCityControl.getCarCityRcCheckList())) {
            RCListVo rcListVoFf = new RCListVo();
            rcListVoFf.setId(String.valueOf(mbTravelstandCarVo.getId()));
            rcListVoFf.setRcList(carCityControl.getCarCityRcCheckList());
            rcListVoFf.setRcType(ReasonCodeTypeEnum.CC.getCode());
            rcListVoFf.setTsType(TravelStandardTypeEnum.Car.getCode());
            travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFf);
        }

        //更新跨城城市RC = 城市RC

        //更新城市地点RC
        if (!CollectionUtils.isEmpty(carAddressControl.getCarAddressRcCheckList())) {
            RCListVo rcListVoFd = new RCListVo();
            rcListVoFd.setId(String.valueOf(mbTravelstandCarVo.getId()));
            rcListVoFd.setRcList(carAddressControl.getCarAddressRcCheckList());
            rcListVoFd.setRcType(ReasonCodeTypeEnum.CA.getCode());
            rcListVoFd.setTsType(TravelStandardTypeEnum.Car.getCode());
            travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFd);
        }

        //更新用车次数RC
        if (!CollectionUtils.isEmpty(carTimesControl.getCarTimesRCCheckList())) {
            RCListVo rcListVoFd = new RCListVo();
            rcListVoFd.setId(String.valueOf(mbTravelstandCarVo.getId()));
            rcListVoFd.setRcList(carTimesControl.getCarTimesRCCheckList());
            rcListVoFd.setRcType(ReasonCodeTypeEnum.CT.getCode());
            rcListVoFd.setTsType(TravelStandardTypeEnum.Car.getCode());
            travelstandReasonCodeService.updateTravelstandReasonCode(rcListVoFd);
        }

        //时间差标
        if (!CollectionUtils.isEmpty(datetimeControl.getCarDatetimes())){
            mbTravelstandCarDatetimeService.delByTsid(carManageVo.getId());
            List<MbTravelstandCarDatetime> datetimes = new ArrayList<>();
            datetimeControl.getCarDatetimes().forEach(item ->{
                MbTravelstandCarDatetime datetime =  new MbTravelstandCarDatetime();
                datetime.setStartTime(item.getStartTime());
                datetime.setEndTime(item.getEndTime());
                datetime.setIsWork(item.getIsWork());
                datetime.setIsNextDay(item.getIsNextDay());
                datetime.setTsid(item.getTsid());
                datetime.setStatus(item.getStatus());
                datetimes.add(datetime);
            });
            mbTravelstandCarDatetimeService.saveBatch(datetimes);
        }

        //城市差标
        if (Objects.nonNull(carCityControl.getCarCityControlVo())) {
            String tsId = String.valueOf(mbTravelstandCarVo.getId());
            mbTravelStandCarCityService.delByTsid(tsId, TravelStandardTypeEnum.Car.getCode());
            List<CarCityVo> cityVos = carCityControl.getCarCityControlVo().getCityVos();
            List<MbTravelStandCarCity> carCityList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(cityVos)) {
                for (CarCityVo item : cityVos) {
                    MbTravelStandCarCity mbTravelStandCarCity = new MbTravelStandCarCity();
                    BeanUtils.copyProperties(item, mbTravelStandCarCity);
                    mbTravelStandCarCity.setControlType(carCityControl.getCarCityControlVo().getControlType());
                    mbTravelStandCarCity.setTsid(mbTravelstandCarVo.getId());
                    mbTravelStandCarCity.setTsType(TravelStandardTypeEnum.Car.getCode());
                    carCityList.add(mbTravelStandCarCity);
                }
            }
            else {
                MbTravelStandCarCity mbTravelStandCarCity = new MbTravelStandCarCity();
                mbTravelStandCarCity.setControlType(carCityControl.getCarCityControlVo().getControlType());
                mbTravelStandCarCity.setTsid(mbTravelstandCarVo.getId());
                mbTravelStandCarCity.setTsType(TravelStandardTypeEnum.Car.getCode());
                carCityList.add(mbTravelStandCarCity);
            }
            mbTravelStandCarCityService.saveBatch(carCityList);

            mbTravelStandCarCrossCityService.delByTsid(tsId, TravelStandardTypeEnum.Car.getCode());
            List<CarCrossCityVo> crossCityVos = carCityControl.getCrossCityControlVo().getCrossCityVos();
            List<MbTravelStandCarCrossCity> carCrossCityList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(crossCityVos)) {
                for (CarCrossCityVo item : crossCityVos) {
                    MbTravelStandCarCrossCity mbTravelStandCarCrossCity = new MbTravelStandCarCrossCity();
                    mbTravelStandCarCrossCity.setLeftCityCode(item.getKey().getCityCode());
                    mbTravelStandCarCrossCity.setLeftCityName(item.getKey().getCityName());
                    mbTravelStandCarCrossCity.setRightCityCode(item.getValue().getCityCode());
                    mbTravelStandCarCrossCity.setRightCityName(item.getValue().getCityName());
                    mbTravelStandCarCrossCity.setControlType(carCityControl.getCrossCityControlVo().getControlType());
                    mbTravelStandCarCrossCity.setTsid(mbTravelstandCarVo.getId());
                    mbTravelStandCarCrossCity.setTsType(TravelStandardTypeEnum.Car.getCode());
                    carCrossCityList.add(mbTravelStandCarCrossCity);
                }
            }
            else {
                MbTravelStandCarCrossCity mbTravelStandCarCrossCity = new MbTravelStandCarCrossCity();
                mbTravelStandCarCrossCity.setControlType(carCityControl.getCrossCityControlVo().getControlType());
                mbTravelStandCarCrossCity.setTsid(mbTravelstandCarVo.getId());
                mbTravelStandCarCrossCity.setTsType(TravelStandardTypeEnum.Car.getCode());
                carCrossCityList.add(mbTravelStandCarCrossCity);
            }
            mbTravelStandCarCrossCityService.saveBatch(carCrossCityList);
        }

        //地点差标
        if (CollectionUtils.isNotEmpty(carAddressControl.getCarAddresses())) {
            String tsId = String.valueOf(mbTravelstandCarVo.getId());
            mbTravelStandCarAddressService.delByTsid(tsId);
            List<MbTravelStandCarAddress> carAddressList = buildCarAddress(carAddressControl, mbTravelstandCarVo);
            mbTravelStandCarAddressService.saveBatch(carAddressList);
        }

        //用车次数差标
        mbTravelStandCarTimesService.delByTsid(mbTravelstandCarVo.getId());
        MbTravelStandCarTimes mbTravelStandCarTimes = new MbTravelStandCarTimes();
        BeanUtils.copyProperties(carTimesControl, mbTravelStandCarTimes);
        mbTravelStandCarTimes.setDayTimes(carTimesControl.getDayTimesCeiling());
        mbTravelStandCarTimes.setMonthTimes(carTimesControl.getMonthTimesCeiling());
        mbTravelStandCarTimes.setTsid(mbTravelstandCarVo.getId());
        mbTravelStandCarTimesService.save(mbTravelStandCarTimes);



        // MARK: 2019/12/19 此处可能产生性能瓶颈，可优化
        //删除车型信息
        mbTravelstandCarModelService.deleteByTsId(mbTravelstandCarVo.getId());
        //循环添加车型信息
        List<Node> searNodes = modelControl.getCarTypeList();
        for (Node node : searNodes) {
            if (node.getIsChecked()) {
                MbTravelstandCarModelVo mbTravelstandCarModelVo = new MbTravelstandCarModelVo();
                mbTravelstandCarModelVo.setTsCarId(mbTravelstandCarVo.getId());
                mbTravelstandCarModelVo.setModelName(node.getName());
                mbTravelstandCarModelVo.setModelCode(node.getCode());
				mbTravelstandCarModelVo.setTsType(TravelStandardTypeEnum.Car.getCode());
                mbTravelstandCarModelService.insert(mbTravelstandCarModelVo);
            }
        }
        //删除旧职位
        travelStandardPostService.deleteByTsidAndTsType(mbTravelstandCarVo.getId(), TravelStandardTypeEnum.Car.getCode());
        //循环添加职位
        String[] jobIds = jobScopeId.split(",");
        for (String jobId : jobIds) {
            TravelStandardPostVo travelStandardPostVo = new TravelStandardPostVo();
            travelStandardPostVo.setPostid(Long.valueOf(jobId));
            travelStandardPostVo.setOrgid(orgId);
            travelStandardPostVo.setTsid(mbTravelstandCarVo.getId());
            travelStandardPostVo.setTstype(TravelStandardTypeEnum.Car.getCode());
            travelStandardPostVo.setTsname(mbTravelstandCarVo.getName());
            travelStandardPostService.insert(travelStandardPostVo);
        }
//        updateOperateLog(
//                oriFlightOperateLogVo,
//                coverMbTravelstandFlightVoToFlightOperateLogVo(travelstandFlightVo)
//        );
    }


    private void checkCarAddress(CarAddressControl carAddressControl) {
        if (CollectionUtils.isEmpty(carAddressControl.getCarAddresses())) {
            return;
        }
        if (CollectionUtils.isNotEmpty(carAddressControl.getCarAddresses())) {
            for (CarAddressVo item : carAddressControl.getCarAddresses()) {
                if(StringUtils.isBlank(item.getLatitude()) || StringUtils.isBlank(item.getLongitude())){
                    throw new CorpBusinessException(ExceptionCodeEnum.Alert, item.getAddress()+"的经纬度不能为空!");
                }
            }
        }
    }

    private List<MbTravelStandCarAddress> buildCarAddress(CarAddressControl carAddressControl, MbTravelstandCarVo mbTravelstandCarVo) {
        List<MbTravelStandCarAddress> carAddressList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(carAddressControl.getCarAddresses())) {
            for (CarAddressVo item : carAddressControl.getCarAddresses()) {
                MbTravelStandCarAddress mbTravelStandCarAddress = new MbTravelStandCarAddress();
                BeanUtils.copyProperties(item, mbTravelStandCarAddress);
                mbTravelStandCarAddress.setTsid(mbTravelstandCarVo.getId());
                mbTravelStandCarAddress.setAddressControlType(carAddressControl.getAddressControlType());
                carAddressList.add(mbTravelStandCarAddress);
            }
        }
        else {
            MbTravelStandCarAddress mbTravelStandCarAddress = new MbTravelStandCarAddress();
            mbTravelStandCarAddress.setTsid(mbTravelstandCarVo.getId());
            mbTravelStandCarAddress.setAddressControlType(carAddressControl.getAddressControlType());
            carAddressList.add(mbTravelStandCarAddress);
        }

        return carAddressList;
    }

    private void checkRequestParam(CarManageVo requestParam) {
        if (requestParam == null) {
            return;
        }
        // 填入的金额不能超过最大值
        if (requestParam.getPriceControl() != null && requestParam.getPriceControl().getPriceCeiling() != null
                && new BigDecimal(requestParam.getPriceControl().getPriceCeiling()).compareTo(new BigDecimal(ServiceConstant.UPPER_LIMIT_PRICE_OF_TRAVEL_STANDARD)) > 0) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.UPPER_LIMIT_PRICE_OF_TRAVEL_STANDARD);
        }

        // 填入的金额不能超过最大值
        if (requestParam.getPriceControl() != null
                && new BigDecimal(requestParam.getPriceControl().getDayPriceCeiling()).compareTo(new BigDecimal(ServiceConstant.UPPER_LIMIT_PRICE_OF_TRAVEL_STANDARD)) > 0) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.UPPER_LIMIT_PRICE_OF_TRAVEL_STANDARD);
        }

        // 填入的金额不能超过最大值
        if (requestParam.getPriceControl() != null
                && new BigDecimal(requestParam.getPriceControl().getMonthPriceCeiling()).compareTo(new BigDecimal(ServiceConstant.UPPER_LIMIT_PRICE_OF_TRAVEL_STANDARD)) > 0) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.UPPER_LIMIT_PRICE_OF_TRAVEL_STANDARD);
        }
    }

    public List<CarManageVo> listTravelstandCar(MbTravelstandCarVo model) {
        List<CarManageVo> carManageVos = new ArrayList<>();
        List<MbTravelstandCarVo> mbTravelstandCarVos = ListUtils.copyList(mbTravelstandCarMapper.list(ObjectUtils.copyProperties(model, MbTravelstandCar.class)), MbTravelstandCarVo.class);
        for (MbTravelstandCarVo mbTravelstandCarVo : mbTravelstandCarVos) {
            //获取相关职位
            List<TravelStandardPost> travelStandardPosts = travelStandardPostService.list(new TravelStandardPostVo() {{
                setTsid(mbTravelstandCarVo.getId());
                setTstype(TravelStandardTypeEnum.Car.getCode());
            }});
            //获取相关rc
            List<MbTravelstandReasonCodeVo> travelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
                setTsId(mbTravelstandCarVo.getId());
                setTsType(TravelStandardTypeEnum.Car.getCode());
            }});
            //获取相关车型信息
            List<MbTravelstandCarModelVo> mbTravelstandCarModelVos = mbTravelstandCarModelService.list(new MbTravelstandCarModelVo() {{
                setTsCarId(mbTravelstandCarVo.getId());
            }});

            //添加用车时间拆标 填充原因
            Map<String,List<Node>> dealReasonCodeVos = BeanConverUtil.groupReasonCodeByType(travelstandReasonCodeVos);
            List<Node> datetimeRCs = dealReasonCodeVos.get(ReasonCodeTypeEnum.CD.getCode());
            if (CollectionUtils.isEmpty(datetimeRCs)){
                insertTravelstandReasonCode(new String[]{"carRcCdTemp"}, mbTravelstandCarVo.getId());
                //刷新数据
                travelstandReasonCodeVos.addAll(travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
                    setTsId(mbTravelstandCarVo.getId());
                    setTsType(TravelStandardTypeEnum.Car.getCode());
                }}));
            }
            //添加用车城市差标，填充原因
            List<Node> cityRCs = dealReasonCodeVos.get(ReasonCodeTypeEnum.CC.getCode());
            if (CollectionUtils.isEmpty(cityRCs)) {
                insertTravelstandReasonCode(new String[]{"carRcCcTemp"}, mbTravelstandCarVo.getId());
                //刷新数据
                travelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
                    setTsId(mbTravelstandCarVo.getId());
                    setTsType(TravelStandardTypeEnum.Car.getCode());
                }});
            }
            //添加用车城市地点差标，填充原因
            List<Node> addressRCs = dealReasonCodeVos.get(ReasonCodeTypeEnum.CA.getCode());
            if (CollectionUtils.isEmpty(addressRCs)) {
                insertTravelstandReasonCode(new String[]{"carRcCaTemp"}, mbTravelstandCarVo.getId());
                //刷新数据
                travelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
                    setTsId(mbTravelstandCarVo.getId());
                    setTsType(TravelStandardTypeEnum.Car.getCode());
                }});
            }

            //添加用车次数差标，填充原因
            List<Node> timesRCs = dealReasonCodeVos.get(ReasonCodeTypeEnum.CT.getCode());
            if (CollectionUtils.isEmpty(timesRCs)) {
                insertTravelstandReasonCode(new String[]{"carRcCtTemp"}, mbTravelstandCarVo.getId());
                //刷新数据
                travelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
                    setTsId(mbTravelstandCarVo.getId());
                    setTsType(TravelStandardTypeEnum.Car.getCode());
                }});
            }
            //获取用车时间配置
            List<MbTravelstandCarDatetime> mbTravelstandCarDatetimes = mbTravelstandCarDatetimeService.selectByTsid(mbTravelstandCarVo.getId().toString());
            //获取用车城市配置
            List<MbTravelStandCarCity> mbTravelStandCarCities = mbTravelStandCarCityService.selectByTsid(mbTravelstandCarVo.getId().toString(), TravelStandardTypeEnum.Car.getCode());

            //获取用车城市配置[跨城]
            List<MbTravelStandCarCrossCity> mbTravelStandCarCrossCities = mbTravelStandCarCrossCityService.selectByTsid(mbTravelstandCarVo.getId().toString(), TravelStandardTypeEnum.Car.getCode());
            //获取用车次数配置
            MbTravelStandCarTimes mbTravelStandCarTimes = mbTravelStandCarTimesService.selectByTsid(mbTravelstandCarVo.getId());
            //获取用车地点配置
            List<MbTravelStandCarAddress> mbTravelStandCarAddresses = mbTravelStandCarAddressService.selectByTsid(mbTravelstandCarVo.getId().toString());
            carManageVos.add(BeanConverUtil.travelstandCarVoToCarManageVo(
                    mbTravelstandCarVo,
                    ListUtils.copyList(travelStandardPosts, TravelStandardPostVo.class),
                    travelstandReasonCodeVos,
                    mbTravelstandCarModelVos,
                    mbTravelstandCarDatetimes,
                    mbTravelStandCarCities,
                    mbTravelStandCarAddresses,
                    mbTravelStandCarCrossCities,
                    mbTravelStandCarTimes
            ));
        }
        return carManageVos;
    }

    @Transactional(rollbackFor = Exception.class)
    public JSONResult deleteTravelstandCar(Long id) {
        MbTravelstandCarVo oriMbTravelstandCarVo = get(id);
        if (oriMbTravelstandCarVo == null) {
            throw new CorpBusinessException(ExceptionCodeEnum.Alert, "差标不存在");
        }
//        TrainOperateLogVo trainOperateLogVo = coverMbTravelstandTrainVoToTrainOperateLogVo(oriMbTravelstandTrainVo);
        //删除差标
        delete(id);
        //删除相关RC
        travelstandReasonCodeService.deleteByTsIdAndTsType(id, TravelStandardTypeEnum.Car.getCode());
        //删除相关车型
        mbTravelstandCarModelService.deleteByTsId(id);
        //删除相关职位关联
        travelStandardPostService.deleteByTsidAndTsType(id, TravelStandardTypeEnum.Car.getCode());
        //删除相关城市关联
        mbTravelStandCarCityService.delByTsid(String.valueOf(id), TravelStandardTypeEnum.Car.getCode());
        //删除相关地点关联
        mbTravelStandCarAddressService.delByTsid(String.valueOf(id));
//        deleteOperateLog(trainOperateLogVo,new TrainOperateLogVo());
        return JSONResult.ok();
    }

    public void updateStandardName(Long id, String title) {
        MbTravelstandCarVo oriMbTravelstandCarVo = get(id);
        if (oriMbTravelstandCarVo == null) {
            throw new CorpBusinessException(ExceptionCodeEnum.Alert, "差标不存在");
        }
        update(new MbTravelstandCarVo().setId(id).setName(title));
    }

    public CarManageSoaVo getTravelStandardDetail(String uid, String orgId) {
        MbTravelstandCarVo mbTravelstandCarVo = getMbTravelstandCarVoByUidAndOrgId(uid, orgId, null);
        if (mbTravelstandCarVo == null) {
            return null;
        }
        //获取相关职位
        List<TravelStandardPost> travelStandardPosts = travelStandardPostService.list(new TravelStandardPostVo() {{
            setTsid(mbTravelstandCarVo.getId());
            setTstype(TravelStandardTypeEnum.Car.getCode());
        }});
        //获取相关rc
        List<MbTravelstandReasonCodeVo> travelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
            setTsId(mbTravelstandCarVo.getId());
            setTsType(TravelStandardTypeEnum.Car.getCode());
        }});
        //获取相关车型信息
        List<MbTravelstandCarModelVo> mbTravelstandCarModelVos = mbTravelstandCarModelService.list(new MbTravelstandCarModelVo() {{
            setTsCarId(mbTravelstandCarVo.getId());
        }});
        //获取用车时间配置
        List<MbTravelstandCarDatetime> mbTravelstandCarDatetimes = mbTravelstandCarDatetimeService.selectByTsid(mbTravelstandCarVo.getId().toString());
        //获取用车城市配置
        List<MbTravelStandCarCity> mbTravelStandCarCities = mbTravelStandCarCityService.selectByTsid(mbTravelstandCarVo.getId().toString(), TravelStandardTypeEnum.Car.getCode());
        //获取用车地点配置
        List<MbTravelStandCarAddress> mbTravelStandCarAddresses = mbTravelStandCarAddressService.selectByTsid(mbTravelstandCarVo.getId().toString());
        //获取用车城市配置[跨城]
        List<MbTravelStandCarCrossCity> mbTravelStandCarCrossCities = mbTravelStandCarCrossCityService.selectByTsid(mbTravelstandCarVo.getId().toString(), TravelStandardTypeEnum.Car.getCode());
        //获取用车次数配置
        MbTravelStandCarTimes mbTravelStandCarTimes = mbTravelStandCarTimesService.selectByTsid(mbTravelstandCarVo.getId());
        return BeanConverUtil.travelstandCarVoToCarManageSoaVo(
                mbTravelstandCarVo,
                ListUtils.copyList(travelStandardPosts, TravelStandardPostVo.class),
                travelstandReasonCodeVos,
                mbTravelstandCarModelVos,
                mbTravelstandCarDatetimes,
                mbTravelStandCarCities,
                mbTravelStandCarAddresses,
                mbTravelStandCarCrossCities,
                mbTravelStandCarTimes
        );
    }

    public CarManageSoaVo getTravelStandardDetailNew(Long tsId) {
        MbTravelstandCar mbTravelstandCar = new MbTravelstandCar();
        mbTravelstandCar.setId(tsId);
        List<MbTravelstandCar> list = mbTravelstandCarMapper.list(mbTravelstandCar);
        if(CollectionUtils.isEmpty(list)){
            return null;
        }
        MbTravelstandCar travelStandCar = list.get(0);

        MbTravelstandCarVo mbTravelstandCarVo = new MbTravelstandCarVo();
        mbTravelstandCarVo.setId(travelStandCar.getId());
        mbTravelstandCarVo.setDatetimeControlType(travelStandCar.getDatetimeControlType());
        mbTravelstandCarVo.setDatetimeSwitch(travelStandCar.getDatetimeSwitch());
        mbTravelstandCarVo.setModelControlType(travelStandCar.getModelControlType());
        mbTravelstandCarVo.setModelSwitch(travelStandCar.getModelSwitch());
        mbTravelstandCarVo.setName(travelStandCar.getName());
        mbTravelstandCarVo.setOrgId(travelStandCar.getOrgId());
        mbTravelstandCarVo.setPriceControlType(travelStandCar.getPriceControlType());
        mbTravelstandCarVo.setPriceSwitch(travelStandCar.getPriceSwitch());
        mbTravelstandCarVo.setPriceUpperLimit(travelStandCar.getPriceUpperLimit());
        mbTravelstandCarVo.setDayPriceUpper(travelStandCar.getDayPriceUpper());
        mbTravelstandCarVo.setMonthPriceUpper(travelStandCar.getMonthPriceUpper());
        mbTravelstandCarVo.setSceneCode(travelStandCar.getSceneCode());
        mbTravelstandCarVo.setSceneName(travelStandCar.getSceneName());
        mbTravelstandCarVo.setCarCitySwitch(travelStandCar.getCarCitySwitch());
        mbTravelstandCarVo.setCarCityControlType(travelStandCar.getCarCityControlType());
        mbTravelstandCarVo.setCarAddressSwitch(travelStandCar.getCarAddressSwitch());
        mbTravelstandCarVo.setCarAddressControlType(travelStandCar.getCarAddressControlType());
        mbTravelstandCarVo.setCarTimesSwitch(travelStandCar.getCarTimesSwitch());
        mbTravelstandCarVo.setCarTimesControlType(travelStandCar.getCarTimesControlType());

        //获取相关职位
        List<TravelStandardPost> travelStandardPosts = travelStandardPostService.list(new TravelStandardPostVo() {{
            setTsid(mbTravelstandCarVo.getId());
            setTstype(TravelStandardTypeEnum.Car.getCode());
        }});
        //获取相关rc
        List<MbTravelstandReasonCodeVo> travelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
            setTsId(mbTravelstandCarVo.getId());
            setTsType(TravelStandardTypeEnum.Car.getCode());
        }});
        //获取相关车型信息
        List<MbTravelstandCarModelVo> mbTravelstandCarModelVos = mbTravelstandCarModelService.list(new MbTravelstandCarModelVo() {{
            setTsCarId(mbTravelstandCarVo.getId());
        }});
        //获取用车时间配置
        List<MbTravelstandCarDatetime> mbTravelstandCarDatetimes = mbTravelstandCarDatetimeService.selectByTsid(mbTravelstandCarVo.getId().toString());
        //获取用车城市配置
        List<MbTravelStandCarCity> mbTravelStandCarCities = mbTravelStandCarCityService.selectByTsid(mbTravelstandCarVo.getId().toString(), TravelStandardTypeEnum.Car.getCode());
        //获取用车地点配置
        List<MbTravelStandCarAddress> mbTravelStandCarAddresses = mbTravelStandCarAddressService.selectByTsid(mbTravelstandCarVo.getId().toString());

        //获取用车城市配置[跨城]
        List<MbTravelStandCarCrossCity> mbTravelStandCarCrossCities = mbTravelStandCarCrossCityService.selectByTsid(mbTravelstandCarVo.getId().toString(), TravelStandardTypeEnum.Car.getCode());
        //获取用车次数配置
        MbTravelStandCarTimes mbTravelStandCarTimes = mbTravelStandCarTimesService.selectByTsid(mbTravelstandCarVo.getId());

        return BeanConverUtil.travelstandCarVoToCarManageSoaVo(
                mbTravelstandCarVo,
                ListUtils.copyList(travelStandardPosts, TravelStandardPostVo.class),
                travelstandReasonCodeVos,
                mbTravelstandCarModelVos,
                mbTravelstandCarDatetimes,
                mbTravelStandCarCities,
                mbTravelStandCarAddresses,
                mbTravelStandCarCrossCities,
                mbTravelStandCarTimes
        );
    }

    public CarManageSoaVo getTravelStandardDetailByPostId(Integer postId) {
        //根据职位查找对应机票差标
        TravelStandardPostVo vo = new TravelStandardPostVo();
        vo.setPostid(Long.valueOf(postId));
        vo.setTstype(TravelStandardTypeEnum.Car.getCode());
        List<TravelStandardPost> travelStandardPostVos = standPostService.list(vo);
        if (travelStandardPostVos == null || travelStandardPostVos.size() == 0) {
            return null;
        }
        //获取对应差标
        MbTravelstandCarVo mbTravelstandCarVo = get(travelStandardPostVos.get(0).getTsid());
//获取相关职位
        List<TravelStandardPost> travelStandardPosts = travelStandardPostService.list(new TravelStandardPostVo() {{
            setTsid(mbTravelstandCarVo.getId());
            setTstype(TravelStandardTypeEnum.Car.getCode());
        }});
        //获取相关rc
        List<MbTravelstandReasonCodeVo> travelStandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo() {{
            setTsId(mbTravelstandCarVo.getId());
            setTsType(TravelStandardTypeEnum.Car.getCode());
        }});
        //获取相关车型信息
        List<MbTravelstandCarModelVo> mbTravelStandCarModelVos = mbTravelstandCarModelService.list(new MbTravelstandCarModelVo() {{
            setTsCarId(mbTravelstandCarVo.getId());
        }});
        //获取用车时间配置
        List<MbTravelstandCarDatetime> mbTravelStandCarDateTimes = mbTravelstandCarDatetimeService.selectByTsid(mbTravelstandCarVo.getId().toString());
        //获取用车城市配置
        List<MbTravelStandCarCity> mbTravelStandCarCities = mbTravelStandCarCityService.selectByTsid(mbTravelstandCarVo.getId().toString(), TravelStandardTypeEnum.Car.getCode());
        //获取用车地点配置
        List<MbTravelStandCarAddress> mbTravelStandCarAddresses = mbTravelStandCarAddressService.selectByTsid(mbTravelstandCarVo.getId().toString());

        //获取用车城市配置[跨城]
        List<MbTravelStandCarCrossCity> mbTravelStandCarCrossCities = mbTravelStandCarCrossCityService.selectByTsid(mbTravelstandCarVo.getId().toString(), TravelStandardTypeEnum.Car.getCode());
        //获取用车次数配置
        MbTravelStandCarTimes mbTravelStandCarTimes = mbTravelStandCarTimesService.selectByTsid(mbTravelstandCarVo.getId());

        return BeanConverUtil.travelstandCarVoToCarManageSoaVo(
                mbTravelstandCarVo,
                ListUtils.copyList(travelStandardPosts, TravelStandardPostVo.class),
                travelStandReasonCodeVos,
                mbTravelStandCarModelVos,
                mbTravelStandCarDateTimes,
                mbTravelStandCarCities,
                mbTravelStandCarAddresses,
                mbTravelStandCarCrossCities,
                mbTravelStandCarTimes
        );
    }

    /**
     * 根据uid和orgId获得对应用车差标
     *
     * @param uid
     * @param orgId 组织id，对应的组织类型可能是公司、部门。
     *              用于从mb_user_org_relation表中拿到对应的职级id
     * @return
     */
    public MbTravelstandCarVo getMbTravelstandCarVoByUidAndOrgId(String uid, String orgId, String postId) {
        Long psId = null;
        if (StringUtils.isNotBlank(postId)){
            psId = Long.valueOf(postId);
        }else{
            if (StringUtils.isBlank(uid)) {
                throw new CorpBusinessException(ExceptionCodeEnum.Alert, "uid不能为空");
            }
            if (StringUtils.isBlank(orgId)) {
                throw new CorpBusinessException(ExceptionCodeEnum.Alert, "组织id不能为空");
            }
            //根据uid和orgId查到对应职位
            PostVo postVo = postService.listPostByUidAndOrgId(uid, orgId);
            //判断岗位是否存在
            if (postVo == null) {
                return null;
            }
            psId = postVo.getId();
        }

        //根据职位查找对应机票差标
        TravelStandardPostVo vo = new TravelStandardPostVo();
        vo.setPostid(psId);
        vo.setTstype(TravelStandardTypeEnum.Car.getCode());
        List<TravelStandardPost> travelStandardPostVos = standPostService.list(vo);
        if (travelStandardPostVos == null || travelStandardPostVos.size() == 0) {
            return null;
        }
        //获取对应差标
        return get(travelStandardPostVos.get(0).getTsid());
    }

    @Override
    public List<MbTravelstandCarVo> selectTravelstandCarByOrgIdAndPostId(CarTravelstandDto request) {
        List<MbTravelstandCar> mbTravelstandCars = mbTravelstandCarMapper.selectTravelstandCarByOrgIdAndPostId(request.getOrgId(), request.getPostId());
        List<MbTravelstandCarVo> voList = ListUtils.copyList(mbTravelstandCars, MbTravelstandCarVo.class);
        return voList;
    }

    @Override
    public CarStandardResponseBO getStandardText(CarTravelstandDto request){
        MbTravelstandCarVo mbTravelstandCarVo = this.getMbTravelstandCarVoByUidAndOrgId(request.getUid(), request.getOrgId(), request.getPostId());

        if (mbTravelstandCarVo == null){
            List<CarDescBO> carDescBOList = new ArrayList<>();
            CarDescBO priceDescBO = new CarDescBO();
            priceDescBO.setTitle("价格管控");
            priceDescBO.setContent("不限");
            carDescBOList.add(priceDescBO);
            CarDescBO carTypeDescBO = new CarDescBO();
            carTypeDescBO.setTitle("车型管控");
            carTypeDescBO.setContent("不限");
            carDescBOList.add(carTypeDescBO);
            return CarStandardResponseBO.create(carDescBOList);
        }

        CarManageSoaVo carControl = this.getTravelStandardDetailNew(mbTravelstandCarVo.getId());
        List<CarDescBO> carDescBOList = new ArrayList<>();
        CarDescBO priceDescBO = new CarDescBO();
        priceDescBO.setTitle("价格管控");
        if (carControl.getPriceControl() == null || CarSwitchEnum.PriceSwitch.N.getCode().equals(carControl.getPriceControl().getStatus())){
            priceDescBO.setContent("不限价格");
        }else {
            Integer priceCeiling = carControl.getPriceControl().getPriceCeiling() == null ? 0 : carControl.getPriceControl().getPriceCeiling();
            priceDescBO.setContent(String.format("￥%s及以下", priceCeiling));
        }
        carDescBOList.add(priceDescBO);

        CarDescBO carTypeDescBO = new CarDescBO();
        carTypeDescBO.setTitle("车型管控");
        if (carControl.getModelControl() == null || CarSwitchEnum.ModelSwitch.N.getCode().equals(carControl.getModelControl().getStatus())
                || !BaseUtils.isNotNull(carControl.getModelControl().getCarTypeList())){
            carTypeDescBO.setContent("不限车型");
        }
        StringBuilder builder = new StringBuilder();
        carControl.getModelControl().getCarTypeList().forEach(t -> {
            if (Boolean.TRUE.equals(t.getIsChecked())){
                if (builder.length() > 0){
                    builder.append("、");
                }
                builder.append(t.getName());
            }
        });
        carTypeDescBO.setContent(builder.toString());
        carDescBOList.add(carTypeDescBO);

        return CarStandardResponseBO.create(carDescBOList);
    }

}
